package com.base.common.interceptor;


import com.base.common.annotation.AllowAccess;
import com.base.common.exception.BizException;
import com.base.common.util.TokenConstants;
import com.base.common.util.TokenUtils;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * common中权限拦截器验证token
 */
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod)) {
            return true; // 静态资源等直接放行
        }

        HandlerMethod method = (HandlerMethod) handler;
        AllowAccess allowAccess = method.getMethodAnnotation(AllowAccess.class);
        if (allowAccess == null) {
            allowAccess = method.getBeanType().getAnnotation(AllowAccess.class);
        }

        if (allowAccess != null && allowAccess.skipAuth()) {
            return true; // 跳过鉴权
        }

        String authHeader = request.getHeader(TokenConstants.TOKEN_HEADER);
        if (authHeader == null || !authHeader.startsWith(TokenConstants.TOKEN_PREFIX)) {
            throw new BizException(HttpServletResponse.SC_UNAUTHORIZED, "缺少Token");
        }

        String token = authHeader.substring(TokenConstants.TOKEN_PREFIX.length());
        Claims claims;
        try {
            claims = TokenUtils.parseToken(token, TokenConstants.ROLE_PORTAL);
        } catch (Exception e) {
            claims = TokenUtils.parseToken(token, TokenConstants.ROLE_ADMIN);
        }

        if (claims == null) {
            throw new BizException(HttpServletResponse.SC_FORBIDDEN, "Token解析失败");
        }

        request.setAttribute("userId", claims.getSubject());
        request.setAttribute("role", claims.get("role"));
        return true;
    }
}
